home *** CD-ROM | disk | FTP | other *** search
/ Internet Info 1994 March / Internet Info CD-ROM (Walnut Creek) (March 1994).iso / networking / ip / ka9q / osrc.arc / AX25USER.C < prev    next >
Encoding:
C/C++ Source or Header  |  1989-02-19  |  3.6 KB  |  182 lines

  1. /* User subroutines for AX.25 */
  2. #include "global.h"
  3. #include "mbuf.h"
  4. #include "timer.h"
  5. #include "iface.h"
  6. #include "lapb.h"
  7. #include "ax25.h"
  8. #include "lapb.h"
  9. #include <ctype.h>
  10.  
  11. extern int32 Axirtt;
  12. struct ax25_cb *cr_ax25();
  13. void lapbstate(),recover();
  14.  
  15. /* Open an AX.25 connection */
  16. struct ax25_cb *
  17. open_ax25(iface,local,remote,window,r_upcall,t_upcall,s_upcall,user)
  18. struct iface *iface;        /* Interface */
  19. struct ax25_addr *local;    /* Local address */
  20. struct ax25_addr *remote;    /* Remote address */
  21. int16 window;            /* Window size in bytes */
  22. void (*r_upcall)();        /* Receiver upcall handler */
  23. void (*t_upcall)();        /* Transmitter upcall handler */
  24. void (*s_upcall)();        /* State-change upcall handler */
  25. int user;            /* User linkage area */
  26. {
  27.     struct ax25_cb *axp;
  28.  
  29.     if((axp = find_ax25(remote)) != NULLAX25 && axp->state != DISCONNECTED)
  30.         return NULLAX25;    /* Only one to a customer */
  31.  
  32.     if(axp == NULLAX25 && (axp = cr_ax25(remote)) == NULLAX25)
  33.         return NULLAX25;
  34.     ASSIGN(axp->remote,*remote);
  35.     ASSIGN(axp->local,*local);
  36.     axp->iface = iface;
  37.     axp->window = window;
  38.     axp->r_upcall = r_upcall;
  39.     axp->t_upcall = t_upcall;
  40.     axp->s_upcall = s_upcall;
  41.     axp->user = user;
  42.  
  43.     switch(axp->state){
  44.     case DISCONNECTED:
  45.         est_link(axp);
  46.         lapbstate(axp,SETUP);
  47.         break;
  48.     case SETUP:
  49.         free_q(&axp->txq);
  50.         break;
  51.     case DISCPENDING:    /* Ignore */
  52.         break;
  53.     case RECOVERY:
  54.     case CONNECTED:
  55.         free_q(&axp->txq);
  56.         est_link(axp);
  57.         lapbstate(axp,SETUP);
  58.         break;
  59.     }
  60.     return axp;
  61. }
  62.  
  63. /* Send data on an AX.25 connection. Caller must provide PID */
  64. int
  65. send_ax25(axp,bp,pid)
  66. struct ax25_cb *axp;
  67. struct mbuf *bp;
  68. int pid;
  69. {
  70.     struct mbuf *bp1;
  71.  
  72.     if(axp == NULLAX25 || bp == NULLBUF)
  73.         return -1;
  74.     while(len_mbuf(bp) > axp->paclen){
  75.         dup_p(&bp1,bp,0,axp->paclen);
  76.         pullup(&bp,NULLCHAR,axp->paclen);
  77.         if(pid != -1){
  78.             bp1 = pushdown(bp1,1);
  79.             bp1->data[0] = pid;
  80.         }
  81.         enqueue(&axp->txq,bp1);
  82.     }
  83.     if(len_mbuf(bp) > 0){
  84.         if(pid != -1){
  85.             bp = pushdown(bp,1);
  86.             bp->data[0] = pid;
  87.         }
  88.         enqueue(&axp->txq,bp);
  89.     }
  90.     return lapb_output(axp);
  91. }
  92.  
  93. /* Receive incoming data on an AX.25 connection */
  94. struct mbuf *
  95. recv_ax25(axp,cnt)
  96. struct ax25_cb *axp;
  97. int16 cnt;
  98. {
  99.     struct mbuf *bp;
  100.  
  101.     if(axp->rxq == NULLBUF)
  102.         return NULLBUF;
  103.  
  104.     bp = axp->rxq;
  105.     axp->rxq = NULLBUF;
  106.  
  107.     /* If this has un-busied us, send a RR to reopen the window */
  108.     if(len_mbuf(bp) >= axp->window)
  109.         sendctl(axp,RESPONSE,RR);
  110.     return bp;
  111. }
  112.  
  113. /* Close an AX.25 connection */
  114. int
  115. disc_ax25(axp)
  116. struct ax25_cb *axp;
  117. {
  118.     if(axp == NULLAX25)
  119.         return -1;
  120.     switch(axp->state){
  121.     case DISCONNECTED:
  122.         break;        /* Ignored */
  123.     case DISCPENDING:
  124.         lapbstate(axp,DISCONNECTED);
  125.         break;
  126.     case CONNECTED:
  127.     case RECOVERY:
  128.         free_q(&axp->txq);
  129.         axp->retries = 0;
  130.         sendctl(axp,COMMAND,DISC|PF);
  131.         stop_timer(&axp->t3);
  132.         start_timer(&axp->t1);
  133.         lapbstate(axp,DISCPENDING);
  134.         break;
  135.     }
  136.     return 0;
  137. }
  138.  
  139. /* Verify that axp points to a valid ax25 control block */
  140. int
  141. ax25val(axp)
  142. struct ax25_cb *axp;
  143. {
  144.     register struct ax25_cb *axp1;
  145.     register int i;
  146.  
  147.     if(axp == NULLAX25)
  148.         return 0;    /* Null pointer can't be valid */
  149.     for(i=0; i < NHASH; i++)
  150.         for(axp1 = Ax25_cb[i];axp1 != NULLAX25; axp1 = axp1->next)
  151.             if(axp1 == axp)
  152.                 return 1;
  153.     return 0;
  154. }
  155.  
  156. /* Force a retransmission */
  157. int
  158. kick_ax25(axp)
  159. struct ax25_cb *axp;
  160. {
  161.     if(!ax25val(axp))
  162.         return -1;
  163.     recover((int *)axp);
  164.     return 0;
  165. }
  166.  
  167. /* Abruptly terminate an AX.25 connection */
  168. int
  169. reset_ax25(axp)
  170. struct ax25_cb *axp;
  171. {
  172.     int user;
  173.  
  174.     if(axp == NULLAX25)
  175.         return -1;
  176.     user = axp->user;
  177.     lapbstate(axp,DISCONNECTED);
  178.     if(user == -1)
  179.         del_ax25(axp);
  180.     return 0;
  181. }
  182.